<template>
  <div class="antv-wrap">
    <div :id="id" style="height: 100%; position: relative">
      <div class="top-right"></div>
      <div class="bottom-left"></div>
    </div>
  </div>
</template>

<script>
import { Chart } from "@antv/g2";
import DataSet from "@antv/data-set";
import dataJson from "./data.json";
import { deepClone, mergeObject, guid } from "@/utils";

export default {
  name: "antv",
  props: {
    option: {
      type: Object,
      default: () => ({}),
    },
    resize: {
      default: () => "",
    },
    renderer: {
      type: String,
      default: () => "canvas", // canvas缩放时会模糊   svg缩放不会模糊
    },
  },
  data() {
    return {
      id: null,
      instance: null,
      dataList: [],
      tempData: [],
    };
  },
  components: {},
  watch: {
    option: {
      handler: function (val) {
        if (this.instance) this.instance.destroy();
        this.renderECharts();
      },
      deep: true,
    },
    resize: function () {
      if (this.instance) {
        this.chartResize();
        this.$nextTick(() => {
          this.instance.destroy();
          this.renderECharts();
        });
      }
    },
  },
  methods: {
    initEChart() {
      this.instance = new Chart({
        container: `${this.id}`,
        height: 500,
        padding: [40, 40, 50, 40],
        autoFit: true,
      });
      this.instance
        .polygon()
        .position("x*y")
        .color("count", "#BAE7FF-#1890FF-#0050B3")
        .style({
          lineWidth: 1,
          stroke: "#fff",
        });

      let ds = new DataSet({ state: { sizeEncoding: false } });
      let dv = ds
        .createView()
        .source(this.dataList)
        .transform({
          sizeByCount: "$state.sizeEncoding",
          type: "bin.hexagon",
          fields: ["x", "y"], // 对应坐标轴上的一个点
          bins: [10, 5],
          as: ["x", "y", "count"],
        });
      this.instance.data(dv.rows); // 更新数据源

      this.instance.axis(false);

      this.instance.tooltip({
        showTitle: false,
        showMarkers: false,
        customItems: (items) => {
          return this.setCustomItems(items[0]);
        }, // 重新定义节点数据
      });

      this.instance.interaction("element-active");
      this.instance.removeInteraction("continuous-filter"); // 移除默认的 legend-filter 数据过滤交互
      this.instance.interaction("continuous-visible-filter"); // 使用分类图例的图形过滤
      this.instance.render(); // 更新图表！
    },
    //重新定义节点数据方法
    setCustomItems(items) {
      let tempItem = deepClone(items);
      let filterData = this.tempData.find(
        (item) => item.remark === `${tempItem.x}` + `${tempItem.y}`
      );

      if (filterData) {
        tempItem.name = filterData.name;
      } else {
        for (let i = 0; i < this.tempData.length; i++) {
          if (
            !this.tempData[i].remark &&
            this.tempData[i].count === tempItem.data.count
          ) {
            this.tempData[i].remark = `${tempItem.x}` + `${tempItem.y}`;
            tempItem.name = this.tempData[i].name;

            break;
          }
        }
      }
      return [tempItem];
    },
    // 将原始数据处理成蜂窝图需要的坐标数据后渲染蜂窝图
    handleData(data) {
      let temp = deepClone(data);
      temp.sort((a, b) => b.count - a.count);
      let coordinate = [],
        dataList = [
          { x: 0, y: 0 },
          { x: 200, y: 200 },
        ],
        c = 20,
        length = 11;

      for (let i = 0; i < length; i++) {
        for (let j = 0; j < length; j++) {
          if (j % 2 === 1) {
            coordinate.push({ x: i * c + c / 2, y: j * c });
          } else {
            coordinate.push({ x: i * c, y: j * c });
          }
        }
      }
      coordinate.forEach((h) => {
        h.dis = this.getPointDistance(110, 100, h.x, h.y);
      });
      coordinate.sort((a, b) => a.dis - b.dis);

      coordinate.forEach((c, i) => {
        if (temp[i]?.count) {
          for (let j = 0; j < temp[i].count; j++) {
            dataList.push(c);
          }
        }
      });
      this.dataList = dataList;

      this.$nextTick(() => {
        this.initEChart();
      });
    },

    getPointDistance(sx, sy, ex, ey) {
      let px = Math.abs(sx - ex);
      let py = Math.abs(sy - ey);
      let dis = Math.sqrt(Math.pow(px, 2) + Math.pow(py, 2));
      return +dis.toFixed(2);
    },

    renderECharts() {
      this.$nextTick(() => {
        if (this.option && this.option.series && this.option.series.length) {
          this.tempData = this.option.series;
          this.handleData(this.option.series);
        }
      });
    },
    chartResize() {
      this.$nextTick(() => {
        let antvWraoContainer = document
          .getElementsByClassName("antv-wrap")[0]
          .getBoundingClientRect();

        let antvContainer = document.getElementById(`${this.id}`);
        antvContainer.style.width = `${antvWraoContainer.height + 100}px`;
      });
    },
  },
  mounted() {
    this.id = guid();
    let antvWraoContainer = document
      .getElementsByClassName("antv-wrap")[0]
      .getBoundingClientRect();

    this.$nextTick(() => {
      let antvContainer = document.getElementById(`${this.id}`);
      antvContainer.style.width = `${antvWraoContainer.height + 100}px`;
      this.renderECharts();
    });

    let that = this;
    // window.addEventListener("resize", () => {
    //   if (that.instance) that.renderECharts();
    // });
  },
};
</script>

<style scoped lang="scss">
.antv-wrap {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  justify-content: center;
}
.top-right {
  position: absolute;
  width: 60px;
  height: 60px;
  background-color: #fff;
  right: 35px;
  top: 35px;
  z-index: 99;
}

.bottom-left {
  position: absolute;
  width: 60px;
  height: 70px;
  background-color: #fff;
  bottom: 40px;
  left: 35px;
  z-index: 99;
}
</style>
